﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace EventScavenger
{
    public partial class PollingFilterEdit : Form
    {
        public PollFilter SelectedPollFilter { get; set; }
        private EventScavengerDAL eventScavengerDAL;
        private bool listViewLoading = false;

        public PollingFilterEdit()
        {
            InitializeComponent();
        }

        public DialogResult Show(EventScavengerDAL eventScavengerDAL)
        {
            this.eventScavengerDAL = eventScavengerDAL;
            LoadListViews();
            return ShowDialog();
        }

        #region Form events
        private void PollingFilterEdit_Load(object sender, EventArgs e)
        {
            if (SelectedPollFilter != null)
            {
                listViewLoading = true;
                txtName.Text = SelectedPollFilter.Name;
                chkExcludeInfo.Checked = SelectedPollFilter.ExcludeInfo;
                chkExcludeWarning.Checked = SelectedPollFilter.ExcludeWarn;
                chkExcludeError.Checked = SelectedPollFilter.ExcludeErr;
                chkExcludeSuccessAudit.Checked = SelectedPollFilter.ExcludeSucAud;
                chkExcludeFailureAudit.Checked = SelectedPollFilter.ExcludeFailAud;
                txtMessageContains.Text = SelectedPollFilter.MessageContains;
                if (SelectedPollFilter.IncludeEventIDs.Count > 0)
                {
                    StringBuilder eventIDIncludesCSV = new StringBuilder();
                    eventIDIncludesCSV.Append(SelectedPollFilter.IncludeEventIDs[0].ToString());
                    for (int i = 1; i < SelectedPollFilter.IncludeEventIDs.Count; i++)
                    {
                        eventIDIncludesCSV.Append(", " + SelectedPollFilter.IncludeEventIDs[i].ToString());
                    }

                    txtEventIDIncludes.Text = eventIDIncludesCSV.ToString();
                }
                if (SelectedPollFilter.ExcludeEventIDs.Count > 0)
                {
                    StringBuilder eventExIncludesCSV = new StringBuilder();
                    eventExIncludesCSV.Append(SelectedPollFilter.ExcludeEventIDs[0].ToString());
                    for (int i = 1; i < SelectedPollFilter.ExcludeEventIDs.Count; i++)
                    {
                        eventExIncludesCSV.Append(", " + SelectedPollFilter.ExcludeEventIDs[i].ToString());
                    }

                    txtEventIDExcludes.Text = eventExIncludesCSV.ToString();
                }
                
                if (SelectedPollFilter.IncludeSources.Count > 0)
                {
                    int sourcePos = 0;
                    //assumption is that both lvwSourcesInclude.Items and SelectedPollFilter.IncludeSources are sorted
                    foreach (string source in SelectedPollFilter.IncludeSources)
                    {
                        while (sourcePos < lvwSourcesInclude.Items.Count 
                            &&  lvwSourcesInclude.Items[sourcePos].Text != source)
                            {
                            sourcePos++;
                        }
                        if (sourcePos < lvwSourcesInclude.Items.Count)
                            lvwSourcesInclude.Items[sourcePos].Checked = true;
                    }
                }
                if (SelectedPollFilter.ExcludeSources.Count > 0)
                {
                    int sourcePos = 0;
                    //assumption is that both lvwSourcesInclude.Items and SelectedPollFilter.ExcludeSources are sorted
                    foreach (string source in SelectedPollFilter.ExcludeSources)
                    {
                        while (sourcePos < lvwSourcesExclude.Items.Count
                            && lvwSourcesExclude.Items[sourcePos].Text != source)
                        {
                            sourcePos++;
                        }
                        if (sourcePos < lvwSourcesExclude.Items.Count)
                            lvwSourcesExclude.Items[sourcePos].Checked = true;
                    }
                }
                listViewLoading = false;
                HighLightCheckedListViewItems(lvwSourcesExclude);
                HighLightCheckedListViewItems(lvwSourcesInclude);
            }
        }
        #endregion

        #region Button events
        private void cmdOK_Click(object sender, EventArgs e)
        {
            if (txtName.Text.Length == 0)
            {
                MessageBox.Show("You must specify a name for the filter", "Poll filter", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                txtName.Focus();
            }
            else
            {
                SelectedPollFilter.Name = txtName.Text;
                SelectedPollFilter.ExcludeInfo = chkExcludeInfo.Checked;
                SelectedPollFilter.ExcludeWarn = chkExcludeWarning.Checked;
                SelectedPollFilter.ExcludeErr = chkExcludeError.Checked;
                SelectedPollFilter.ExcludeSucAud = chkExcludeSuccessAudit.Checked;
                SelectedPollFilter.ExcludeFailAud = chkExcludeFailureAudit.Checked;
                SelectedPollFilter.MessageContains = txtMessageContains.Text;
                SelectedPollFilter.IncludeEventIDs = new List<int>();
                if (txtEventIDIncludes.Text.Trim().Length > 0)
                {
                    string[] eventIDstrs = txtEventIDIncludes.Text.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                    int eventID;
                    foreach (string eventIDstr in eventIDstrs)
                    {
                        if (int.TryParse(eventIDstr, out eventID))
                        {
                            SelectedPollFilter.IncludeEventIDs.Add(eventID);
                        }
                        else
                        {
                            MessageBox.Show("Invalid input or not a number! - " + eventIDstr, "Poll filter", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                            txtEventIDIncludes.Focus();
                            return;
                        }
                    }
                }
                SelectedPollFilter.ExcludeEventIDs = new List<int>();
                if (txtEventIDExcludes.Text.Trim().Length > 0)
                {
                    string[] eventIDstrs = txtEventIDExcludes.Text.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                    int eventID;
                    foreach (string eventIDstr in eventIDstrs)
                    {
                        if (int.TryParse(eventIDstr, out eventID))
                        {
                            SelectedPollFilter.ExcludeEventIDs.Add(eventID);
                        }
                        else
                        {
                            MessageBox.Show("Invalid input or not a number! - " + eventIDstr, "Poll filter", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                            txtEventIDExcludes.Focus();
                            return;
                        }
                    }
                }
                SelectedPollFilter.IncludeSourceIDs = new List<int>();
                SelectedPollFilter.IncludeSources = new List<string>();
                if (lvwSourcesInclude.CheckedItems.Count > 0)
                {
                    foreach (ListViewItem lvi in lvwSourcesInclude.CheckedItems)
                    {
                        EventSource es = (EventSource)lvi.Tag;
                        SelectedPollFilter.IncludeSourceIDs.Add(es.SourceID);
                        SelectedPollFilter.IncludeSources.Add(es.Source);
                    }
                }
                SelectedPollFilter.ExcludeSourceIDs = new List<int>();
                SelectedPollFilter.ExcludeSources = new List<string>();
                if (lvwSourcesExclude.CheckedItems.Count > 0)
                {
                    foreach (ListViewItem lvi in lvwSourcesExclude.CheckedItems)
                    {
                        EventSource es = (EventSource)lvi.Tag;
                        SelectedPollFilter.ExcludeSourceIDs.Add(es.SourceID);
                        SelectedPollFilter.ExcludeSources.Add(es.Source);
                    }
                }

                DialogResult = DialogResult.OK;
                Close();
            }
        } 
        private void cmdEventSourcesIncludeUncheckAll_Click(object sender, EventArgs e)
        {
            listViewLoading = true;
            foreach (ListViewItem lvi in lvwSourcesInclude.CheckedItems)
            {
                lvi.Checked = false;
            }
            listViewLoading = false;
            HighLightCheckedListViewItems(lvwSourcesInclude);
        }
        private void cmdEventSourcesExcludeUncheckAll_Click(object sender, EventArgs e)
        {
            listViewLoading = true;
            foreach (ListViewItem lvi in lvwSourcesExclude.CheckedItems)
            {
                lvi.Checked = false;
            }
            listViewLoading = false;
            HighLightCheckedListViewItems(lvwSourcesExclude);
        }
        #endregion

        #region Loading
        private void LoadListViews()
        {
            Cursor.Current = Cursors.WaitCursor;
            lvwSourcesInclude.Items.Clear();
            lvwSourcesExclude.Items.Clear();
            try
            {
                listViewLoading = true;
                lvwSourcesInclude.BeginUpdate();
                lvwSourcesExclude.BeginUpdate();

                foreach (EventSource es in eventScavengerDAL.GetEventSourceList())
                {
                    ListViewItem lvi1 = new ListViewItem(es.Source);
                    lvi1.Tag = es;
                    lvwSourcesInclude.Items.Add(lvi1);
                    ListViewItem lvi2 = new ListViewItem(es.Source);
                    lvi2.Tag = es;
                    lvwSourcesExclude.Items.Add(lvi2);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            finally
            {
                lvwSourcesInclude.EndUpdate();
                lvwSourcesExclude.EndUpdate();
                listViewLoading = false;
            }
            Cursor.Current = Cursors.Default;
        }
        private void HighLightCheckedListViewItems(ListView lvw)
        {
            if (!listViewLoading)
            {
                lvw.BeginUpdate();
                foreach (ListViewItem lvi in lvw.Items)
                {
                    HighLightCheckedListViewItem(lvi);
                }
                lvw.EndUpdate();
            }
        }
        private void HighLightCheckedListViewItem(ListViewItem lvi)
        {
            if (lvi != null)
            {
                if (lvi.Checked)
                    lvi.BackColor = Color.Yellow;
                else
                    lvi.BackColor = SystemColors.Window;
            }
        }
        #endregion

        #region Quick find
        private void txtEventSourcesIncludeQuickFind_TextChanged(object sender, EventArgs e)
        {
            if (txtEventSourcesIncludeQuickFind.Text.Length > 0)
            {
                timerQuickFind1.Enabled = false; //cancel any previous event
                timerQuickFind1.Enabled = true;
            }
        }

        private void timerQuickFind1_Tick(object sender, EventArgs e)
        {
            timerQuickFind1.Enabled = false;
            if (txtEventSourcesIncludeQuickFind.Text.Length > 0)
            {
                string quickFilter = txtEventSourcesIncludeQuickFind.Text.ToLower();
                foreach (ListViewItem lvi in lvwSourcesInclude.Items)
                {
                    if (lvi.Text.ToLower().Contains(quickFilter))
                    {
                        lvi.Selected = true;
                        lvi.EnsureVisible();
                        break;
                    }
                }
            }
        }

        private void txtEventSourcesExcludeQuickFind_TextChanged(object sender, EventArgs e)
        {
            if (txtEventSourcesExcludeQuickFind.Text.Length > 0)
            {
                timerQuickFind2.Enabled = false; //cancel any previous event
                timerQuickFind2.Enabled = true;
            }
        }

        private void timerQuickFind2_Tick(object sender, EventArgs e)
        {
            timerQuickFind2.Enabled = false;
            if (txtEventSourcesExcludeQuickFind.Text.Length > 0)
            {
                string quickFilter = txtEventSourcesExcludeQuickFind.Text.ToLower();
                foreach (ListViewItem lvi in lvwSourcesExclude.Items)
                {
                    if (lvi.Text.ToLower().Contains(quickFilter))
                    {
                        lvi.Selected = true;
                        lvi.EnsureVisible();
                        break;
                    }
                }
            }
        } 
        #endregion

        #region List view events
        private void lvwSourcesInclude_ItemChecked(object sender, ItemCheckedEventArgs e)
        {
            if (!listViewLoading)
            {
                HighLightCheckedListViewItem(e.Item);
            }
        }
        private void lvwSourcesExclude_ItemChecked(object sender, ItemCheckedEventArgs e)
        {
            if (!listViewLoading)
            {
                HighLightCheckedListViewItem(e.Item);
            }
        } 
        #endregion

    }
}
